"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.validateAll = void 0;

var _utils = require("./utils");

var _validateMessageCN = require("./validateMessageCN");

var _validateMessage = require("./validateMessage");

var _asyncValidator = _interopRequireDefault(require("async-validator"));

var _lodashEs = require("lodash-es");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

var validateAll = function validateAll(_ref) {
  var formData = _ref.formData,
      flatten = _ref.flatten,
      _ref$isRequired = _ref.isRequired,
      isRequired = _ref$isRequired === void 0 ? true : _ref$isRequired,
      _ref$touchedKeys = _ref.touchedKeys,
      touchedKeys = _ref$touchedKeys === void 0 ? [] : _ref$touchedKeys,
      _ref$locale = _ref.locale,
      locale = _ref$locale === void 0 ? 'cn' : _ref$locale,
      _ref$validateMessages = _ref.validateMessages,
      validateMessages = _ref$validateMessages === void 0 ? {} : _ref$validateMessages;

  var _schema = (0, _utils.getSchemaFromFlatten)(flatten);

  if (Object.keys(_schema).length === 0) return Promise.resolve();
  var descriptor = (0, _utils.getDescriptorFromSchema)({
    schema: _schema,
    isRequired: isRequired
  }).fields;
  window.descriptor = descriptor; // console.log(descriptor, '&&&& descriptor', formData);

  var touchVerifyList = []; // 如果是最后的校验，所有key都touch了，就不用算这个了
  // 因为要整个构建validator在list的情况太复杂了，所以required单独拿出来处理，但是这边有不少单独处理逻辑，例如message

  if (!isRequired) {
    touchedKeys.forEach(function (key) {
      var keyRequired = (0, _utils.isPathRequired)(key, _schema);
      var val = (0, _lodashEs.get)(formData, key);
      var nullValue = [undefined, null, ''].indexOf(val) > -1; // 注意 0 不是

      var isEmptyMultiSelect = Array.isArray(val) && val.length === 0;

      if ((nullValue || isEmptyMultiSelect) && keyRequired.required) {
        var _message = keyRequired.message || validateMessages.required || '${title}必填';

        touchVerifyList.push({
          name: key,
          error: [_message]
        });
      }
    });
  }

  var cn = _validateMessageCN.defaultValidateMessagesCN;
  var en = _validateMessage.defaultValidateMessages; // TODO: 有些情况会出现没有rules，需要看一下，先兜底

  var validator;

  try {
    validator = new _asyncValidator.default(descriptor);
  } catch (error) {
    return Promise.resolve([]);
  }

  var messageFeed = locale === 'en' ? en : cn;
  (0, _lodashEs.merge)(messageFeed, validateMessages);
  validator.messages(messageFeed);
  return validator.validate(formData || {}).then(function (res) {
    if (touchVerifyList.length > 0) return touchVerifyList;
    return [];
  }).catch(function (_ref2) {
    var errors = _ref2.errors,
        fields = _ref2.fields;
    // error的name改成正常的path
    var normalizedErrors = (0, _utils.getArray)(errors).map(function (err) {
      var _path = (0, _utils.formatPathFromValidator)(err.field);

      return {
        name: _path,
        error: [err.message]
      };
    }); // 添加touched的required

    normalizedErrors = [].concat(_toConsumableArray(normalizedErrors), touchVerifyList); // 合并同名的error

    var _errorFields = [];
    normalizedErrors.forEach(function (item) {
      var matchIndex = _errorFields.findIndex(function (ele) {
        return ele.name === item.name;
      });

      if (matchIndex === -1) {
        _errorFields.push(item);
      } else {
        _errorFields[matchIndex].error = [].concat(_toConsumableArray(_errorFields[matchIndex].error), _toConsumableArray(item.error));
      }
    });
    return _errorFields;
  });
}; // useEffect(() => {
//   const descriptor = {
//     roles: {
//       type: 'array',
//       required: true,
//       defaultField: {
//         type: 'object',
//         fields: {
//           street: { type: 'string', required: true },
//           city: { type: 'string', required: true, message: 'invalid zip' },
//           zip: [
//             {
//               type: 'string',
//               required: true,
//               message: 'invalid zip',
//             },
//             {
//               len: 8,
//               message: 'xxx',
//             },
//           ],
//           res: {
//             type: 'array',
//             required: true,
//             defaultField: {
//               type: 'object',
//               fields: {
//                 city: { type: 'string', required: true },
//               },
//             },
//           },
//         },
//       },
//     },
//     name: {
//       type: 'string',
//       required: true,
//       validator: (rule, value) => value === 'muji',
//     },
//     age: {
//       type: 'number',
//       min: 12,
//       max: 13,
//       message: 'asdfadsf',
//       // asyncValidator: (rule, value) => {
//       //   return new Promise((resolve, reject) => {
//       //     if (value < 18) {
//       //       reject('too young'); // reject with error message
//       //     } else {
//       //       resolve();
//       //     }
//       //   });
//       // },
//     },
//   };
//   const validator = new Validator(descriptor);
//   // validator.validate({ name: 'muji' }, (errors, fields) => {
//   //   if (errors) {
//   //     // validation failed, errors is an array of all errors
//   //     // fields is an object keyed by field name with an array of
//   //     // errors per field
//   //     return handleErrors(errors, fields);
//   //   }
//   //   // validation passed
//   // });
//   validator
//     .validate({ name: 'muji', age: 16, roles: [{ zip: '123', res: [{}] }] })
//     .then(() => {
//       // validation passed or without error message
//     })
//     .catch(({ errors, fields }) => {
//       return handleErrors(errors, fields);
//     });
// }, []);


exports.validateAll = validateAll;
var d3 = {
  list: {
    type: 'array',
    defaultField: {
      type: 'object',
      fields: {
        userName: [{
          bind: false,
          title: 'User Name',
          type: 'string',
          rules: [{
            min: 5,
            message: '长度需要大于5'
          }, {
            max: 12
          }]
        }, {
          min: 5,
          message: '长度需要大于5'
        }, {
          max: 12
        }],
        selectName: {
          title: '单选',
          type: 'string',
          enum: ['a', 'b', 'c'],
          enumNames: ['早', '中', '晚'],
          required: true
        },
        checkboxName: {
          title: '是否判断',
          type: 'boolean',
          valuePropName: 'checked'
        }
      }
    }
  }
};
var d2 = {
  list: {
    type: 'array',
    defaultField: {
      type: 'object',
      fields: {
        userName: [{
          bind: false,
          title: 'User Name',
          type: 'string',
          rules: [{
            min: 5,
            message: '长度需要大于5'
          }, {
            max: 12
          }]
        }, {
          min: 5,
          message: '长度需要大于5'
        }, {
          max: 12
        }],
        selectName: {
          title: '单选',
          type: 'string',
          enum: ['a', 'b', 'c'],
          enumNames: ['早', '中', '晚'],
          required: true
        },
        checkboxName: {
          title: '是否判断',
          type: 'boolean',
          valuePropName: 'checked'
        }
      }
    }
  }
};